package com.turtle.service.impl;

import com.turtle.aop.RedissonLock;
import com.turtle.constant.StatusConst;
import com.turtle.dto.BlogSortInfoDto;
import com.turtle.dto.BlogSortListDto;
import com.turtle.dto.BlogSortParam;
import com.turtle.dto.BlogSortStatusParam;
import com.turtle.entity.sql.BlogSort;
import com.turtle.exception.UserAlertException;
import com.turtle.extend.BlogSortConverter;
import com.turtle.mapper.BlogSortMapper;
import com.turtle.service.BlogService;
import com.turtle.service.BlogSortService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * @author lijiayu
 * @date 2020/7/21
 * @description
 */
@Service
public class BlogSortServiceImpl implements BlogSortService {
    @Autowired
    private BlogSortMapper blogSortMapper;
    @Autowired
    private BlogService blogService;

    @Autowired
    private BlogSortConverter blogSortConverter;

    /**
     * 获取分类集合
     * @param status
     * @param userId
     * @return
     */
    @Override
    @Transactional(readOnly = true)
    public List<BlogSortListDto> getList(Integer status, Long userId) {
        //分类集合
        List<BlogSort> list = blogSortMapper.getListByStatus(status, userId);
        if(CollectionUtils.isEmpty(list)){
            return List.of();
        }
        //文章数
        Map<Long,Long> countMap = blogService.getCountMapByUserId(userId);

        return blogSortConverter.toListDto(list,countMap);
    }

    /**
     * 获取分类信息
     * @param id
     * @return
     */
    @Override
    public BlogSortInfoDto get(Long id) {
        BlogSort blogSort = Optional.ofNullable(blogSortMapper.selectById(id))
                .orElseThrow(() -> new UserAlertException("找不到对应的分类"));
        return blogSortConverter.toDto(blogSort);
    }

    /**
     * 新增分类
     * @param param
     * @param userId
     */
    @Override
    @RedissonLock(key = "userId")
    @Transactional(rollbackFor = Exception.class)
    public void add(BlogSortParam param,Long userId) {
        //校验名称是否重复
        if(checkNameRepeat(null,param.getName(),userId)){
            throw new UserAlertException("分类已存在");
        }
        BlogSort blogSort = blogSortConverter.toEntity(param, userId);
        blogSortMapper.insert(blogSort);
    }

    /**
     * 编辑
     * @param param
     * @param userId
     */
    @Override
    @RedissonLock(key = "#param.id")
    @Transactional(rollbackFor = Exception.class)
    public void update(BlogSortParam param, Long userId) {
        validBlogSortId(param.getId(),userId);
        if(checkNameRepeat(param.getId(),param.getName(),userId)){
            throw new UserAlertException("分类已存在");
        }
        BlogSort blogSort = blogSortConverter.toEntity(param, userId);
        blogSortMapper.updateById(blogSort);
    }

    /**
     * 彻底删除(只允许存在回收站的删除)
     * @param id
     * @param userId
     */
    @Override
    public void delete(Long id, Long userId) {
        BlogSort old = validBlogSortId(id, userId);
        if(old.getStatus()!=StatusConst.RECYCLE){
            throw new UserAlertException("只允许彻底删除回收站的分类");
        }
        blogSortMapper.deleteById(id);
    }

    /**
     * 修改状态
     * @param param
     * @param userId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateStatus(BlogSortStatusParam param, Long userId) {
        validBlogSortId(param.getId(),userId);

        BlogSort blogSort = BlogSort.builder()
                .id(param.getId())
                .status(param.getStatus())
                .build();
        blogSortMapper.updateById(blogSort);
    }

    /**
     * 校验分类数据是否正常
     * @param id
     * @param userId
     */
    private BlogSort validBlogSortId(Long id,Long userId){
        BlogSort oldBlogSort = Optional.ofNullable(blogSortMapper.selectById(id))
                .orElseThrow(() -> new UserAlertException("找不到对应的分类"));
        if(!oldBlogSort.getUserId().equals(userId)){
            throw new UserAlertException("分类与用户不匹配");
        }
        return oldBlogSort;
    }

    /**
     * 校验名称是否重复  true:重复  false:不重复
     * @param id
     * @param name
     * @param userId
     * @return
     */
    private Boolean checkNameRepeat(Long id,String name,Long userId){
        int count = blogSortMapper.getCountByIdNameUserId(id, name, userId);
        return count > 0;
    }
}
